<template>
    <div class="waterfall-container" ref="containerRef" @scroll="handleScroll">
      <div class="waterfall-list">
        <div
          class="waterfall-item"
          v-for="(item, index) in resultList"
          :key="index"
          :style="{
            width: `${item.width}px`,
            height: `${item.height}px`,
            transform: `translate3d(${item.x}px, ${item.y}px, 0)`,
          }"
        >{{ item.id }}
        <!-- {{ resultList }} -->
          <slot name="item" v-bind="item">
            <!-- {{ item }} -->
          </slot>
        </div>
      </div>
    </div>
  </template>
  <script setup>
  import { ref, onMounted, computed, nextTick, onUnmounted } from "vue";
//   import { createList,getRemo teData,throttle, debounce,getRandomElement,getRandomNumber } from "../test/utils";
  import { getPostListAPI } from "../../api/community";
  import { getRemoteData, throttle, debounce } from "../test/utils";
  const props = defineProps({
    // 间距
    gap: {
      type: Number,
      default: 10,
    },
    // 列数
    columns: {
      type: Number,
      default: 3,
    },
    // 距离底部
    bottom: {
      type: Number,
      default: 0,
    },
    // 分页大小
    pageSize: {
      type: Number,
      default: 10,
    },
  });
  
  // 容器ref
  const containerRef = ref(null);
  
  // 卡片宽度
  const cardWidth = ref(0);
  
  // 列高度
  const columnHeight = ref(new Array(props.columns).fill(0));
  
  // 数据list
  const resultList = ref([]);
  
  // 当前页码
  const pageNo = ref(1);
  
  // 加载状态
  const loading = ref(false);
  
  // 计算最小列高度及其下标
  const minColumn = computed(() => {
    let minIndex = -1,
      minHeight = Infinity;
  
    columnHeight.value.forEach((item, index) => {
      if (item < minHeight) {
        minHeight = item;
        minIndex = index;
      }
    });
  
    return {
      minIndex,
      minHeight,
    };
  });
  

  const colorList = ['red', 'blue', 'green', 'pink', 'yellow', 'orange', 'purple', 'brown', 'gray', 'skyblue']

  
  // 获取接口数据
  const getData = async () => {
    // loading.value = true;
    // const list = createList(props.pageSize);
    // const resList = await getRemoteData(list, 300).finally(
    //   () => (loading.value = false)
    // );
    let params={
        pageNo:pageNo.value,
        pageSize:10,
        userId:1
    }
    const list =await getPostListAPI(params)
    const resList = list.data.data.rows.map(item => ({
    ...item, // 保留原有对象的所有属性
    background: getRandomElement(colorList), // 添加背景颜色
    width: getRandomNumber(200, 600), // 添加宽度
    height: getRandomNumber(400, 700), // 添加高度
    x: 0, // 初始位置X
    y: 0  // 初始位置Y
}));
    pageNo.value++;
    resultList.value = [...resultList.value, ...getList(resList)];
    console.log(resultList.value)
  };
  
  // 滚动到底部获取新一页数据-节流
  const handleScroll = throttle(() => {
    const { scrollTop, clientHeight, scrollHeight } = containerRef.value;
    const bottom = scrollHeight - clientHeight - scrollTop;
    if (bottom <= (props.bottom+1000)) {
      !loading.value && getData();
    }
  });
  
  // 拼装数据结构
  const getList = (list) => {
    return list.map((x, index) => {
      const cardHeight = Math.floor((x.height * cardWidth.value) / x.width);
      const { minIndex, minHeight } = minColumn.value;
      const isInit = index < props.columns && resultList.length <= props.pageSize;
      if (isInit) {
        columnHeight.value[index] = cardHeight + props.gap;
      } else {
        columnHeight.value[minIndex] += cardHeight + props.gap;
      }
  
      return {
        ...x,
        width: cardWidth.value,
        height: cardHeight,
        x: isInit
          ? index % props.columns !== 0
            ? index * (cardWidth.value + props.gap)
            : 0
          : minIndex % props.columns !== 0
          ? minIndex * (cardWidth.value + props.gap)
          : 0,
        y: isInit ? 0 : minHeight,
        background: x.background,
      };
    });
  };
  
  // 监听元素
  const resizeObserver = new ResizeObserver(() => {
    handleResize();
  });
  
  // 重置计算宽度以及位置
  const handleResize = debounce(() => {
    const containerWidth = containerRef.value.clientWidth;
    cardWidth.value =
      (containerWidth - props.gap * (props.columns - 1)) / props.columns;
    columnHeight.value = new Array(props.columns).fill(0);
    resultList.value = getList(resultList.value);
  });
  
  const init = () => {
    if (containerRef.value) {
      const containerWidth = containerRef.value.clientWidth;
      cardWidth.value =
        (containerWidth - props.gap * (props.columns - 1)) / props.columns;
      getData();
      resizeObserver.observe(containerRef.value);
    }
  };
  
  onMounted(() => {
    init();
  });
  // 取消监听
  onUnmounted(() => {
    containerRef.value && resizeObserver.unobserve(containerRef.value);
  });
  </script>
  
<style lang="scss">
  .waterfall {
    &-container {
      width: 100%;
      height: 100%;
      overflow-y: scroll;
      overflow-x: hidden;
    }
  
    &-list {
      width: 100%;
      position: relative;
    }
    &-item {
      position: absolute;
      left: 0;
      top: 0;
      box-sizing: border-box;
      transition: all 0.3s;
    }
  }
</style>
  
  